#include <iostream>
#include <vector>
#include <cstdlib>
#include <cassert>
#include <pthread.h>
#include <unistd.h>

#define N 10

struct myThread
{
    pthread_t tid;
    char nameBuffer[64];
};

struct returnValues
{
    size_t exit_code;
    int exit_result;
};

void *start_routine(void *arg)
{
    myThread *th = static_cast<myThread *>(arg); // static_cast<T>安全地强制类型转换为为T类型
    int cnt = 10;
    while (cnt)
    {
        printf("this is new thread and tid:%x threadName: %s cnt: %d &cnt: %p\n", th->tid, th->nameBuffer, cnt, &cnt);
        --cnt;
        sleep(1);

        // if(cnt == 5) pthread_exit(nullptr);
        // if(cnt == 5) pthread_cancel(th->tid);
    }

    // pthread_exit(nullptr);
    pthread_exit((void*)"exit");

    // return (void*)100;

    // returnValues* ret = new returnValues();
    // ret->exit_code = 10;
    // ret->exit_result = 100;

    // return (void*)ret;
}

int main()
{
    std::vector<myThread *> threads;
    threads.reserve(N);

    for (int i = 0; i < N; ++i)
    {
        myThread *pthread = new myThread();

        snprintf(pthread->nameBuffer, sizeof(pthread->nameBuffer) - 1, "thread_%d", i + 1);
        pthread_create(&pthread->tid, nullptr, start_routine, pthread);

        threads.push_back(pthread);
    }

    // 主线程
    for (auto &th : threads)
    {
        std::cout << "this is main thread and new thread create success." << std::endl;
        sleep(1);

        // delete th;
    }

    for(auto& it : threads)
    {
        void* ret = nullptr;
        int n = pthread_join(it->tid, &ret);
        assert(n == 0);

        std::cout << "new thread exit_code: " << (const char*)ret << std::endl;


        // std::cout << "new thread exit_code: " << ((returnValues*)ret)->exit_code << " exit_result: " << ((returnValues*)ret)->exit_result << std::endl;
        // delete (returnValues*)ret;

        delete it;
        sleep(1);
    }

    while(true)
    {
        std::cout << "this is main thread and new thread has destory." << std::endl;
        sleep(1);
    }


    return 0;
}